package com.zzyy.study.desensitization;

import com.fasterxml.jackson.core.JsonGenerator;
import com.fasterxml.jackson.databind.BeanProperty;
import com.fasterxml.jackson.databind.JsonMappingException;
import com.fasterxml.jackson.databind.JsonSerializer;
import com.fasterxml.jackson.databind.SerializerProvider;
import com.fasterxml.jackson.databind.ser.ContextualSerializer;

import java.io.IOException;
import java.util.Objects;


/**
 * 自定义一个脱敏的jackson序列化器，这个序列化器会对标注了脱敏注解的字段进行处理，
 * 会将注解上的脱敏策略取出来，使用脱敏策略对原字符串进行替换，
 * 然后输出替换后的字符串。
 */
public class DesensitizationJsonSerializable extends JsonSerializer<String> implements ContextualSerializer
{

    //脱敏策略
    private DesensitizationStrategyEnum desensitizationStrategy;

    @Override
    public void serialize(String s, JsonGenerator gen, SerializerProvider serializers) throws IOException
    {
        // 使用脱敏策略将字符串处理后序列化到json中
        gen.writeString(desensitizationStrategy.getDesensitization().apply(s));
    }

    @Override
    public JsonSerializer<?> createContextual(SerializerProvider prov, BeanProperty property)
            throws JsonMappingException
    {
        // 获取属性上的 Desensitization 注解
        Desensitization annotation = property.getAnnotation(Desensitization.class);

        // 注解不为空 && 属性类型必须是字符串类型
        if (Objects.nonNull(annotation) && Objects.equals(String.class, property.getType().getRawClass()))
        {
            //设置脱敏策略
            this.desensitizationStrategy = annotation.value();
            return this;
        }
        // 返回默认的序列化器
        return prov.findValueSerializer(property.getType(), property);
    }

}